﻿// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2023 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

using Furion.DynamicApiController;

namespace Abc.Application;

/// <summary>
///     数据配置
/// </summary>
[ApiDescriptionSettings("HtAdmin", Name = "DataConfig")]
[MaApi("API", "DataConfig", "数据配置", PCode = "API")]
[IgnoreAntiforgeryToken]
public class DataConfigService : IDataConfigService, ITransient, IDynamicApiController
{
    private readonly ILogger<DataConfigService> _logger;
    private readonly IRepository<SysDataConfig> _repository;

    public DataConfigService(ILogger<DataConfigService> logger
        , IRepository<SysDataConfig> repository)
    {
        _logger = logger;
        _repository = repository;
    }

    /// <summary>
    ///     新增或更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [MaPermission("新增或更新一条", "InsertOrUpdate")]
    public async Task InsertOrUpdate(DataConfigInput input)
    {
        if (string.IsNullOrWhiteSpace(input.PKey)) input.PKey = "";
        if (input.Id > 0)
        {
            //验证 父级下 唯一 Key是否存在
            var isexit =
                await _repository.AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key && o.Id != input.Id);
            if (isexit) throw Oops.Bah("唯一标识Key不能重复");
            var dbentity = await _repository.FindAsync(input.Id);
            input.Adapt(dbentity);
            //await _db.UpdateAsync(dbentity);
        }
        else
        {
            //验证 父级下 唯一 Key是否存在
            var isexit = await _repository.AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key);
            if (isexit) throw Oops.Bah("唯一标识Key不能重复");
            var addentity = input.Adapt<SysDataConfig>();
            var newEntity = await _repository.InsertAsync(addentity);
        }
    }

    /// <summary>
    ///     删除一条
    /// </summary>
    /// <param name="id"></param>
    [MaPermission("删除一条", "Delete")]
    public async Task Delete(long id)
    {
        if (id <= 0) throw Oops.Bah("id不能为0");
        await _repository.DeleteAsync(id);
    }

    /// <summary>
    ///     批量删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [MaPermission("批量删除", "BatchDelete")]
    public async Task BatchDelete(string ids)
    {
        var idtemps = ids.ToLongList();
        await _repository.Where(o => idtemps.Contains(o.Id)).ExecuteDeleteAsync();
    }

    /// <summary>
    ///     查询所有
    /// </summary>
    /// <returns></returns>
    [MaPermission("查询所有", "GetAll")]
    public List<DataConfigOut> GetAll()
    {
        return _repository.DetachedEntities.ToList().Adapt<List<DataConfigOut>>();
    }

    /// <summary>
    ///     查询一条
    /// </summary>
    /// <param name="id"></param>
    [MaPermission("查询一条", "Get")]
    public async Task<TEntity> Get<TEntity>(long id)
    {
        var dbentity = await _repository.FirstOrDefaultAsync(o => o.Id == id);
        if (dbentity == null) return default;
        return dbentity.Adapt<TEntity>();
    }

    /// <summary>
    ///     查询一条
    /// </summary>
    /// <param name="key"></param>
    [MaPermission("查询一条", "GetByKey")]
    public async Task<DataConfigOut> GetByKey(string key)
    {
        var dbentity = await _repository.FirstOrDefaultAsync(o =>
            !string.IsNullOrWhiteSpace(o.Key) && o.Key.ToLower().Trim() == key.ToLower().Trim());
        if (dbentity == null) return null;
        return dbentity.Adapt<DataConfigOut>();
    }

    /// <summary>
    ///     分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [MaPermission("分页查询", "GetAllByPage")]
    public async Task<LayuiPagedList<DataConfigOut>> GetAllByPageToLayui(DataConfigQuery searchQuery)
    {
        var queryable = _repository.DetachedEntities.AsQueryable();
        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {
            var kw = searchQuery.KeyWords.ToLower();
            queryable = queryable.Where(o => o.Key.Contains(kw));
        }


        var pagedlist = await queryable.OrderByDescending(o => o.Id).ProjectToType<DataConfigOut>()
            .ToLayuiPagedListAsync(searchQuery.Page, searchQuery.Limit);

        pagedlist.data = HandleChildren(pagedlist.data);

        return pagedlist;
    }

    #region 查询下拉树

    /// <summary>
    ///     查询菜单下来树
    /// </summary>
    /// <returns></returns>
    [MaPermission("查询菜单下来树", "GetDtree")]
    public async Task<Dtree> GetDtree(string pid = "")
    {
        var dataconfigs = await _repository.DetachedEntities.SelectAsync(o =>
            new DtreeEntity { id = o.Key, pid = o.PKey, name = o.Name, sort = o.Sort });
        var dtree = dataconfigs.GetDtree(pid = "");
        return dtree;
    }

    #endregion 查询下拉树

    /// <summary>
    ///     获取系统设置
    /// </summary>
    /// <returns></returns>
    [ApiExplorerSettings(IgnoreApi = true)]
    public async Task<TEntity> GetSetting<TEntity>(long pid) where TEntity : new()
    {
        //var entities = await _cacheService.GetDataConfigEntities();
        var settings = await _repository.Where(o => o.PId == pid).ToListAsync();
        var settingdto = new TEntity();
        foreach (var setting in settings) settingdto.FieldSetValue(setting.Key, setting.Value);
        return settingdto;
    }

    /// <summary>
    ///     获取系统设置
    /// </summary>
    /// <returns></returns>
    [ApiExplorerSettings(IgnoreApi = true)]
    public async Task<TEntity> GetSetting<TEntity>(string pkey) where TEntity : new()
    {
        //var entities = await _cacheService.GetDataConfigEntities();
        var settings = await _repository.Where(o => o.PKey == pkey).ToListAsync();
        var settingdto = new TEntity();
        foreach (var setting in settings) settingdto.FieldSetValue(setting.Key, setting.Value);
        return settingdto;
    }

    /// <summary>
    ///     新增或修改设置
    /// </summary>
    /// <param name="input">输入对象</param>
    /// <param name="pkey">父级</param>
    /// <returns></returns>
    [MaPermission("新增或修改设置", "AddOrUpdateSetting")]
    public async Task AddOrUpdateSetting(object input, string pkey)
    {
        var dataconfigs = await _repository.Where(o => o.PKey == pkey).ToListAsync();

        //var pdataconfig = await Entities.FirstOrDefaultAsync(o => o.Key == pkey);

        var propertys = input.GetDictionaryEntityInfo();
        foreach (var property in propertys)
        {
            var dataconfig = dataconfigs.FirstOrDefault(o => o.Key != null && o.Key == property.Key && o.PKey == pkey);
            if (dataconfig == null)
            {
                //不存在，创建一个新的配置
                var newdataconfig = new SysDataConfig
                {
                    //PId = pdataconfig.Id,
                    PKey = pkey,
                    Key = property.Key,
                    //Value = property.Value.GetValue("Value"),
                    //Name = property.Value.GetValue("Description"),
                    Value = property.Value.Value,
                    Name = property.Value.Description,
                    IsEnable = true
                };
                var rnewdataconfig = await _repository.InsertAsync(newdataconfig);
            }
            else
            {
                dataconfig =
                    await _repository.FirstAsync(o => o.Key != null && o.Key == dataconfig.Key && o.PKey == pkey);
                dataconfig.Value = property.Value.Value; //值
                dataconfig.Name = property.Value.Description; //名称
            }
        }
    }

    /// <summary>
    ///     设置状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="state"></param>
    /// <param name="field">字段名</param>
    /// <returns></returns>
    [MaPermission("设置状态", "SetState")]
    public async Task SetState(long id, bool state, string field)
    {
        var entity = await _repository.FindAsync(id);

        switch (field.ToLower())
        {
            case "isenable":
            {
                entity.IsEnable = state;
            }
                break;
            //case "isdeleted":
            //    {
            //        entity.IsDeleted = state;
            //    }
            //    break;
        }
    }

    private List<DataConfigOut> HandleChildren(IEnumerable<DataConfigOut> menus, string pKey = "")
    {
        var menuItems = new List<DataConfigOut>();
        foreach (var menuitem in menus.Where(o => o.PKey != null && o.PKey.ToLower() == pKey.ToLower())
                     .OrderBy(o => o.Sort))
        {
            if (!string.IsNullOrWhiteSpace(menuitem.Key) &&
                menus.Any(o => o.PKey != null && o.PKey.ToLower() == pKey.ToLower()))
                menuitem.children = HandleChildren(menus, menuitem.Key);
            menuitem.IsParent = !string.IsNullOrWhiteSpace(pKey);
            menuItems.Add(menuitem);
        }

        return menuItems;
    }
}